/* 
    这个 js  就是一个工具类文件
    里面可以放很多将来我可能会使用到的函数
*/
/* 
    用来求范围之间的随机数
    @param {a}  范围下限
    @param {b}  范围上限
    @return 随机数
*/
function getRandom(a, b) {
    return Math.floor(Math.random() * (b - a + 1) + a)
}
/* 
    用来求随机颜色字符串
    @return 随机颜色字符串
*/
function getColor() {
    return 'rgb(' + getRandom(0, 255) + ',' + getRandom(0, 255) + ',' + getRandom(0, 255) + ')'
}

/* 
    绑定事件
    @param {ele} 要绑定事件的元素
    @param {type} 事件类型
    @param {fn} 事件处理函数 
*/
function on(ele, type, fn) {
    if (ele.addEventListener) {
        if(type.indexOf('on') === 0){
            type = type.slice(2)
        }
        ele.addEventListener(type,fn)
    }else{
        if(type.indexOf('on') !== 0){
            type = 'on' + type
        }
        ele.attachEvent(type,fn)
    }
}

/* 
    解绑事件
*/
function off(ele,type,fn){
    if(ele.removeEventListener){
        if(type.indexOf('on') === 0){
            type = type.slice(2)
        }
        ele.removeEventListener(type,fn)
    }else{
        if(type.indexOf('on') !== 0){
            type = 'on' + type
        }
        ele.detachEvent(type,fn)
    }
}

/* 
    获取元素
    @params {selector} 选择器
    @params {context}  元素范围
    @return 获取到的元素或者元素集合
*/
function my$(selector,context){
    context = context || document
    if(selector.indexOf('#') === 0){
        return document.getElementById(selector.slice(1))
    }else if(selector.indexOf('.') === 0){
        return context.getElementsByClassName(selector.slice(1))
    }else{
        return context.querySelectorAll(selector)
    }
}

/* 
    获取元素的非行内样式
    @param {ele} 要获取或者设置样式的元素
    @param {attr} 要获取或者设置的样式属性名
    @param {value} 要设置的属性值
    @return 获取到的元素的样式
*/
function css(ele,attr,value){
    if(!value){
        return window.getComputedStyle ? window.getComputedStyle(ele)[attr] : ele.currentStyle[attr]
    }
    ele.style[attr] = value
}

/* 
    @param {ele} 要执行动画的元素
    @param {options} 要执行动画的属性的终点值
    @param {duration} 动画执行的时间
    @param {fn} 动画执行完毕的回调函数
 */
function animate(ele, options, duration,fn) {
    clearInterval(ele.timer)
    const start = {}, range = {}
    for (let key in options) {
        start[key] = parseInt(css(ele, key))
        range[key] = options[key] - start[key]
    }
    const startTime = new Date().getTime()
    ele.timer = setInterval(() => {
        const sjc = Math.min(new Date().getTime() - startTime,duration)
        for (let attr in options) {
            const result = attr === 'opacity' ? range[attr] / duration * sjc + start[attr] : range[attr] / duration * sjc + start[attr] + 'px'
            ele.style[attr] = result
        }
        if (sjc === duration) {
            clearInterval(ele.timer)
            fn && fn()  
        }
    }, 10)
}
/* 
    淡入
*/
function fadeIn(ele,duration,fn){
    css(ele,'display','block')
    css(ele,'opacity','0')
    animate(ele,{ opacity : 1 },duration,fn)
}
/* 
    淡出
*/
function fadeOut(ele,duration,fn){
    css(ele,'display','block')
    css(ele,'opacity','1')
    animate(ele,{ opacity : 0 },duration,fn)
}
/* 
    获取元素 内容 + padding 
*/
function inWidth(ele){
    return parseInt(css(ele,'width')) + parseInt(css(ele,'paddingLeft')) + parseInt(css(ele,'paddingRight'))
}
function inHeight(ele){
    return parseInt(css(ele,'height')) + parseInt(css(ele,'paddingTop')) + parseInt(css(ele,'paddingBottom'))
}
/* 
    获取元素内容 + padding  + border
*/
function outWidth(ele){
    return parseInt(css(ele,'width')) + parseInt(css(ele,'paddingLeft')) + parseInt(css(ele,'paddingRight')) + parseInt(css(ele,'borderLeftWidth')) + parseInt(css(ele,'borderRightWidth'))
}
function outHeight(ele){
    return parseInt(css(ele,'height')) + parseInt(css(ele,'paddingTop')) + parseInt(css(ele,'paddingBottom'))+ parseInt(css(ele,'borderTopWidth')) + parseInt(css(ele,'borderBottomWidth'))
}

/* 
    获取 cookie
*/
function getCookie(str){
    const arr = document.cookie.split('; ')
    let res 
    arr.forEach(item => {
        const arr1 = item.split('=')
        if(arr1[0] === str){
            res = arr1[1]
        }
    })
    return res
}
/* 
    设置 cookie
*/
function setCookie(key,value,s){
    const date = new Date()
    let time = date.getTime() - 8 * 60 * 60 * 1000 + s * 1000
    date.setTime(time)
    document.cookie = `${key}=${value};path=/;expires=${date}`
}

/* 
    删除 cookie
*/
function deleteCookie(key){
    setCookie(key,'随便',-1)
}

function ajax(options){
    const defaultOptions = {
        type:'get',
        dataType:'',
        async:true
    }
    // options 传入的参数
    for(let key in options){
        // console.log(key)
        // 把 options 里面的每一项数据都添加到 defaultOptions 里面
        // 如果 defaultOptions 里面本来就有这条数据就会被覆盖了
        defaultOptions[key] = options[key]
    }
    // console.log(defaultOptions)
    // url 和 success 必须要传入
    if(!defaultOptions.url){
        // 手动抛出一个错误
        throw new Error('url 是必传项')
    }
    if(!defaultOptions.success || typeof(defaultOptions.success) !== 'function'){
        throw new Error('success 是必传项 并且必须是一个函数')
    }
    const { type ,data,url,success,dataType } = defaultOptions
    // 创建一个 ajax 对象
    const xhr = new XMLHttpRequest()
    if(type.toUpperCase() === 'GET' && data){
        xhr.open('get',url+'?'+data)
    }else{
        // post 请求
        // get 请求但是没有参数
        xhr.open(type,url)
    }
    if(type.toUpperCase() === 'POST' && data){
        xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
        xhr.send(data)
    }else{
        // get 请求
        // post 请求但是没有参数
        xhr.send()
    }
    xhr.onreadystatechange = () => {
        if(xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)){
            dataType === 'json' ? success(JSON.parse(xhr.responseText)) : success(xhr.responseText)
        }
    }

}

function PAjax(options){
    return new Promise((resolve,reject) => {
        ajax({
            ...options,
            success(res){
                resolve(res)
            }
        })
    })
}
